package com.xjscrm.console.service.common.sms.impl;

import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.xjscrm.common.constant.ResponseMsg;
import com.xjscrm.common.enums.SmsType;
import com.xjscrm.common.exception.BusinessException;
import com.xjscrm.common.result.ResponseCode;
import com.xjscrm.common.utils.RandomUtil;
import com.xjscrm.console.biz.CaptchaService;
import com.xjscrm.console.param.login.VerifyDto;
import com.xjscrm.console.service.common.sms.SmsService;
import com.xjscrm.console.service.common.user.UserService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author jianghan
 * @date 2019-04-03 14:16
 */
@Service
public class SmsServiceImpl implements SmsService {

    private static Logger logger = LoggerFactory.getLogger(SmsServiceImpl.class);
    private String product = "Dysmsapi";
    private String domain = "dysmsapi.aliyuncs.com";
    @Value("${aliyun.accessKeyId}")
    private String accessKeyId;
    @Value("${aliyun.accessKeySecret}")
    private String accessKeySecret;
    @Value("${aliyun.sms.title}")
    private String smsTitle;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserService userService;

    @Autowired
    private CaptchaService captchaService;


    @Override
    public void sendCode(VerifyDto verifyDto) {
        if (verifyDto.getType()==1){
            //滑块验证
            captchaService.authByCaptcha(verifyDto.getNonceStr(),verifyDto.getValue());
            sms(verifyDto.getPhone(), SmsType.REGISTER);
        }
        if (verifyDto.getType()==2){
//            userService.getUserByPhone(verifyDto.getPhone());
            //滑块验证
            captchaService.authByCaptcha(verifyDto.getNonceStr(),verifyDto.getValue());
            sms(verifyDto.getPhone(),SmsType.LOGIN);
        }
        if (verifyDto.getType()==3){
            userService.getUserByPhone(verifyDto.getPhone());
            //滑块验证
            captchaService.authByCaptcha(verifyDto.getNonceStr(),verifyDto.getValue());
            sms(verifyDto.getPhone(),SmsType.PASSWORD);
        }
        if (verifyDto.getType()==4){
            //滑块验证
            sms(verifyDto.getPhone(),SmsType.AUTHINFO);
        }
    }

    private void sms(String phone, SmsType smsType) {
        if (StringUtils.isBlank(phone) || phone.length()!=11){
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, ResponseMsg.MOBILE_ERROR);
        }
        // 获取验证码
        String code = RandomUtil.getSmsCode(4);
        redisTemplate.opsForValue().set(String.format(smsType.getDesc(),phone),code,5, TimeUnit.MINUTES);
        Map<String, Object> params = new HashMap<>();
        params.put("code", code);
        sms(smsType.getTempId(),phone,params);
    }

    @Override
    public void smsLoginForbid(String phone, String templateId) {
        if (StringUtils.isBlank(phone) || phone.length()!=11){
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, ResponseMsg.MOBILE_ERROR);
        }
        sms(templateId,phone);
    }


    private void sms(String tempId, String mobile, Object params) {
        try {
            String paramStr = JSONObject.toJSONString(params);
            logger.info("tempId is :{},mobile is :{},params is :{}",new Object[]{tempId,mobile,paramStr});
            //可自助调整超时时间
            System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
            System.setProperty("sun.net.client.defaultReadTimeout", "10000");

            //初始化acsClient,暂不支持region化
            IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
            DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
            IAcsClient acsClient = new DefaultAcsClient(profile);

            //组装请求对象
            SendSmsRequest request = new SendSmsRequest();
            request.setPhoneNumbers(mobile);
            //短信签名
            request.setSignName(smsTitle);
            //短信模板
            request.setTemplateCode(tempId);
            //模板中的变量替换JSON串
            request.setTemplateParam(paramStr);

            //hint 此处可能会抛出异常，注意catch
            SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
            logger.info("sendSmsResponse:{},{},{}",new Object[]{sendSmsResponse.getRequestId(),sendSmsResponse.getCode(),sendSmsResponse.getMessage()});

            String respCode = sendSmsResponse.getCode();
            if ("isv.BUSINESS_LIMIT_CONTROL".equals(respCode)){
                throw new BusinessException("操作频率太快，请稍后再试!"+params);
            }
        } catch (ClientException e) {
            logger.error("sms error:{}",e);
        }
    }

    private void sms(String tempId, String mobile){
        try {
            logger.info("tempId is :{},mobile is :{}",new Object[]{tempId,mobile});
            //可自助调整超时时间
            System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
            System.setProperty("sun.net.client.defaultReadTimeout", "10000");

            //初始化acsClient,暂不支持region化
            IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
            DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
            IAcsClient acsClient = new DefaultAcsClient(profile);

            //组装请求对象
            SendSmsRequest request = new SendSmsRequest();
            request.setPhoneNumbers(mobile);
            //短信签名
            request.setSignName(smsTitle);
            //短信模板
            request.setTemplateCode(tempId);

            //hint 此处可能会抛出异常，注意catch
            SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
            logger.info("sendSmsResponse:{},{},{}",new Object[]{sendSmsResponse.getRequestId(),sendSmsResponse.getCode(),sendSmsResponse.getMessage()});

            String respCode = sendSmsResponse.getCode();
            if ("isv.BUSINESS_LIMIT_CONTROL".equals(respCode)){
                throw new BusinessException("操作频率太快，请稍后再试!");
            }

        }catch (ClientException e){
            logger.error("sms error:{}",e);
        }
    }

}